home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 5 / MACVOGL- / EXAMPLES / LIGHTS.C < prev    next >
C/C++ Source or Header  |  1992-07-19  |  6KB  |  253 lines

  1. #ifdef SGI
  2. #include <gl/gl.h>
  3. #include "device.h"
  4. #else
  5. #include "vogl.h"
  6. #include "vodevice.h"
  7. #endif
  8.  
  9. #include <math.h>
  10. #include <stdio.h>
  11.  
  12. #define RADIUS 0.9
  13. #define TWOPI    6.28318530
  14. /*#define PI        3.14159265*/
  15.  
  16. float   blackvec[3] = {0.0, 0.0, 0.0};    /* black RGB */
  17. Matrix  idmat = {1.0, 0.0, 0.0, 0.0,    /* identity matrix */
  18.          0.0, 1.0, 0.0, 0.0,
  19.          0.0, 0.0, 1.0, 0.0,
  20.          0.0, 0.0, 0.0, 1.0};
  21.  
  22. /* define a polygon with some structures */
  23. typedef struct
  24. {
  25.     Coord   x;
  26.     Coord   y;
  27.     Coord   z;
  28. }       POINT;
  29.  
  30. typedef struct
  31. {                /* lighted polygon struct */
  32.     POINT   vertex[4];
  33.     POINT   normal[4];
  34. }       POLYGON;
  35.  
  36. int     number_of_polys;    /* cylinder polygon count */
  37. POLYGON *polygon;        /* polygon list pointer */
  38.  
  39. /* define property arrays */
  40. float   shiny_material[] =
  41. {
  42.  SPECULAR, 0.8, 0.8, 0.8,    /* lt. gray reflectance */
  43.  DIFFUSE, 0.4, 0.4, 0.4,    /* gray reflectance */
  44.  SHININESS, 30.0,        /* focused highlight */
  45.  LMNULL};
  46.  
  47. float   purple_material[] =
  48. {
  49.  SPECULAR, 0.3, 0.3, 0.3,    /* gray reflectance */
  50.  DIFFUSE, 0.8, 0.0, 0.8,    /* purple reflectance */
  51.  SHININESS, 3.0,        /* unfocused highlight */
  52.  AMBIENT, 0.2, 0.2, 0.2,    /* purple reflectance */
  53.  LMNULL};
  54.  
  55. float   blue_light[] =
  56. {
  57.  LCOLOR, 0.0, 0.0, 0.6,        /* blue light */
  58.  POSITION, 0.0, 0.1, 0.0, 0.0,    /* Y axis at infinity */
  59.  LMNULL};
  60.  
  61. /*
  62. ** def_light_calc()
  63. ** Tell the Graphics Library to DEFINE a 
  64. ** lighting calculation that accounts for 
  65. ** ambient, diffuse, and specular reflection.
  66. ** This lighting calculation defines a second 
  67. ** material and light source 
  68. */
  69. def_light_calc()
  70. {
  71.     lmdef(DEFMATERIAL, 1, 11, shiny_material);
  72.     lmdef(DEFMATERIAL, 2, 15, purple_material);
  73.     lmdef(DEFLIGHT, 1, 0, NULL);
  74.     lmdef(DEFLIGHT, 2, 10, blue_light);
  75.     lmdef(DEFLMODEL, 1, 0, NULL);
  76. }
  77.  
  78. /*
  79. ** use_light_calc()
  80. ** Tell the Graphics Library to USE
  81. ** the lighting calculation that we 
  82. ** defined earlier.
  83. */
  84. use_light_calc()
  85. {
  86.     lmbind(LIGHT0, 1);        /* use light source description 1 */
  87.     lmbind(LIGHT1, 2);        /* use light source description 2 */
  88.     lmbind(LMODEL, 1);        /* use lighting model 1 */
  89. };
  90.  
  91. /* 
  92. ** make_cylinder()
  93. ** Draw a cylinder using (2 * n) polygons
  94. ** to approximate the curvature and n polygons
  95. ** to describe the length. This requires (2 * n^2)
  96. ** polygons to describe the cylinder. Compute
  97. ** the surface normal at each vertex so we can 
  98. ** use the hardware lighting facility to perform
  99. ** lighting calculations.
  100. */
  101. make_cylinder(n)
  102. int     n;
  103. {
  104.     POLYGON *p;            /* polygon list pointer */
  105.     float   theta, dtheta,    /* current angle and angle */
  106.     /* increment around section */
  107.             x, dx;        /* current position and */
  108.     /* increment along cylinder side */
  109.     int     vertex_i;        /* vertex counter */
  110.  
  111.     /* allocate and point to enough */
  112.     /* memory for all the polygons */
  113.     number_of_polys = 2 * n * n;
  114.     p = polygon = (POLYGON *)
  115.     malloc(number_of_polys * sizeof(POLYGON));
  116.  
  117.     dx = 3.0 / n;        /* n polygons for 3.0 units of length */
  118.     dtheta = PI / n;        /* length of polygon along curvature */
  119.  
  120.     /* for each layer of polygons */
  121.     /* along length of cylinder ... */
  122.     for (x = -1.5; x < 1.5; x = x + dx)
  123.     {
  124.     /* ... and for each polygon */
  125.     /* describing the circumference */
  126.     for (theta = 0.0; theta < TWOPI; theta += dtheta)
  127.     {
  128.         /* calculate the four points */
  129.         /* describing the polygon */
  130.         p->vertex[0].x = p->vertex[1].x = x;
  131.         p->vertex[0].y = p->vertex[3].y =
  132.         RADIUS * cos(theta);
  133.         p->vertex[0].z = p->vertex[3].z =
  134.         RADIUS * sin(theta);
  135.         p->vertex[1].y = p->vertex[2].y =
  136.         RADIUS * cos(theta + dtheta);
  137.         p->vertex[1].z = p->vertex[2].z =
  138.         RADIUS * sin(theta + dtheta);
  139.         p->vertex[2].x = p->vertex[3].x = x + dx;
  140.  
  141.         /* calculate the four normals of unit length */
  142.         for (vertex_i = 0; vertex_i < 4; vertex_i++)
  143.         {
  144.         p->normal[vertex_i].x = 0;
  145.         p->normal[vertex_i].y =
  146.             p->vertex[vertex_i].y / RADIUS;
  147.         p->normal[vertex_i].z =
  148.             p->vertex[vertex_i].z / RADIUS;
  149.         }
  150.         p++;
  151.         if (qtest()) {
  152.             qread(&val);
  153.             gexit();
  154.             exit(0);
  155.         }
  156.     }
  157.     }
  158. }
  159.  
  160.  
  161. /* 
  162. ** draw_cylinder()
  163. ** This subroutine increments through the 4
  164. ** vertices describing each polygon of the 
  165. ** cylinder defined in make cylinder. Note
  166. ** how a normal is sent to the graphics 
  167. ** hardware before each vertex so that the 
  168. ** lighting facility will compute the color
  169. ** for each vertex based on the lighting
  170. ** parameters that we are using.
  171. */
  172. draw_cylinder()
  173. {
  174.     POLYGON *p;            /* pointer into polygon list */
  175.     int     poly_i;        /* polygon counter */
  176.  
  177.     /* start at first polygon and */
  178.     /* increment through all of them */
  179.     p = polygon;
  180.     for (poly_i = 0; poly_i < number_of_polys; poly_i++)
  181.     {
  182.     bgnpolygon();        /* describe the polygon */
  183.     n3f(&p->normal[0]);
  184.     v3f(&p->vertex[0]);
  185.     n3f(&p->normal[1]);
  186.     v3f(&p->vertex[1]);
  187.     n3f(&p->normal[2]);
  188.     v3f(&p->vertex[2]);
  189.     n3f(&p->normal[3]);
  190.     v3f(&p->vertex[3]);
  191.     endpolygon();
  192.     p++;            /* go to the next polygon */
  193.     }
  194. }
  195.  
  196. /*
  197. ** Main Program
  198. */
  199. main()
  200. {
  201.     int     i;
  202.  
  203.     /* set up graphics environment */
  204.     prefposition(0, 900, 0, 900);
  205.     winopen("cylinder");
  206.     RGBmode();
  207.     doublebuffer();
  208.     gconfig();
  209.     zbuffer(TRUE);
  210.  
  211.     /* Use mmode to set up projection */
  212.     /* and viewing matrices for lighting */
  213.     mmode(MVIEWING);
  214.     perspective(400, 1.0, 4.0, 12.0);
  215.     loadmatrix(idmat);
  216.     lookat(0.0, 0.0, 8.0, 0.0, 0.0, 0.0, 0);
  217.  
  218.     /* let there be light !!! */
  219.     def_light_calc();
  220.     use_light_calc();
  221.  
  222.     /* Rotate cylinders in 2 deg. increments */
  223.     /* about the Y and Z axis for 180 frames */
  224.     make_cylinder(25);
  225.     for (i = 0; i < 180; i++)
  226.     {
  227.     c3f(blackvec);
  228.     clear();
  229.     zclear();
  230.  
  231.     pushmatrix();
  232.     rot(i * 2.0, 'Z');
  233.     rot(i * 2.0, 'Y');
  234.  
  235.     /* use white shiny material for cyl 1 */
  236.     lmbind(MATERIAL, 1);
  237.     draw_cylinder();
  238.  
  239.     pushmatrix();
  240.     rot(90.0, 'Y');
  241.     scale(0.9, 0.9, 0.9);
  242.  
  243.     /* use purple rough material for cyl 2 */
  244.     lmbind(MATERIAL, 2);
  245.     draw_cylinder();
  246.  
  247.     popmatrix();
  248.     popmatrix();
  249.     swapbuffers();
  250.     }
  251.     sleep(3);
  252. }
  253.